


<!DOCTYPE html>
<html id="htmlId">
<head>
  <title>Coverage Report > Level</title>
  <style type="text/css">
    @import "../../css/coverage.css";
    @import "../../css/highlight-idea.css";
  </style>
  <script type="text/javascript" src="../../js/highlight.pack.js"></script>
</head>

<body>
<div class="content">
<div class="breadCrumbs">
Current scope:     <a href="../../index.html">all classes</a>
    <span class="separator">|</span>
    <a href="../index.html">nl.tudelft.jpacman.level</a>
</div>

<h1>Coverage Summary for Class: Level (nl.tudelft.jpacman.level)</h1>

<table class="coverageStats">

<tr>
  <th class="name">Class</th>
<th class="coverageStat 
">
  Method, %
</th>
<th class="coverageStat 
">
  Line, %
</th>
</tr>
<tr>
  <td class="name">Level</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/15)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/93)
  </span>
</td>
</tr>
  <tr>
    <td class="name">Level$NpcMoveTask</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/8)
  </span>
</td>
  </tr>
<tr>
  <td class="name"><strong>Total</strong></td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/17)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    0%
  </span>
  <span class="absValue">
    (0/101)
  </span>
</td>
</tr>
</table>

<br/>
<br/>


<pre>
<div class="sourceCode" id="sourceCode"><i class="no-highlight">1</i>&nbsp;package nl.tudelft.jpacman.level;
<i class="no-highlight">2</i>&nbsp;
<i class="no-highlight">3</i>&nbsp;import java.util.ArrayList;
<i class="no-highlight">4</i>&nbsp;import java.util.HashMap;
<i class="no-highlight">5</i>&nbsp;import java.util.HashSet;
<i class="no-highlight">6</i>&nbsp;import java.util.List;
<i class="no-highlight">7</i>&nbsp;import java.util.Map;
<i class="no-highlight">8</i>&nbsp;import java.util.Map.Entry;
<i class="no-highlight">9</i>&nbsp;import java.util.Set;
<i class="no-highlight">10</i>&nbsp;import java.util.concurrent.Executors;
<i class="no-highlight">11</i>&nbsp;import java.util.concurrent.ScheduledExecutorService;
<i class="no-highlight">12</i>&nbsp;import java.util.concurrent.TimeUnit;
<i class="no-highlight">13</i>&nbsp;
<i class="no-highlight">14</i>&nbsp;import nl.tudelft.jpacman.board.Board;
<i class="no-highlight">15</i>&nbsp;import nl.tudelft.jpacman.board.Direction;
<i class="no-highlight">16</i>&nbsp;import nl.tudelft.jpacman.board.Square;
<i class="no-highlight">17</i>&nbsp;import nl.tudelft.jpacman.board.Unit;
<i class="no-highlight">18</i>&nbsp;import nl.tudelft.jpacman.npc.Ghost;
<i class="no-highlight">19</i>&nbsp;
<i class="no-highlight">20</i>&nbsp;/**
<i class="no-highlight">21</i>&nbsp; * A level of Pac-Man. A level consists of the board with the players and the
<i class="no-highlight">22</i>&nbsp; * AIs on it.
<i class="no-highlight">23</i>&nbsp; *
<i class="no-highlight">24</i>&nbsp; * @author Jeroen Roosen 
<i class="no-highlight">25</i>&nbsp; */
<b class="nc"><i class="no-highlight">26</i>&nbsp;@SuppressWarnings(&quot;PMD.TooManyMethods&quot;)</b>
<i class="no-highlight">27</i>&nbsp;public class Level {
<i class="no-highlight">28</i>&nbsp;
<i class="no-highlight">29</i>&nbsp;    /**
<i class="no-highlight">30</i>&nbsp;     * The board of this level.
<i class="no-highlight">31</i>&nbsp;     */
<i class="no-highlight">32</i>&nbsp;    private final Board board;
<i class="no-highlight">33</i>&nbsp;
<i class="no-highlight">34</i>&nbsp;    /**
<i class="no-highlight">35</i>&nbsp;     * The lock that ensures moves are executed sequential.
<i class="no-highlight">36</i>&nbsp;     */
<b class="nc"><i class="no-highlight">37</i>&nbsp;    private final Object moveLock = new Object();</b>
<i class="no-highlight">38</i>&nbsp;
<i class="no-highlight">39</i>&nbsp;    /**
<i class="no-highlight">40</i>&nbsp;     * The lock that ensures starting and stopping can&#39;t interfere with each
<i class="no-highlight">41</i>&nbsp;     * other.
<i class="no-highlight">42</i>&nbsp;     */
<b class="nc"><i class="no-highlight">43</i>&nbsp;    private final Object startStopLock = new Object();</b>
<i class="no-highlight">44</i>&nbsp;
<i class="no-highlight">45</i>&nbsp;    /**
<i class="no-highlight">46</i>&nbsp;     * The NPCs of this level and, if they are running, their schedules.
<i class="no-highlight">47</i>&nbsp;     */
<i class="no-highlight">48</i>&nbsp;    private final Map&lt;Ghost, ScheduledExecutorService&gt; npcs;
<i class="no-highlight">49</i>&nbsp;
<i class="no-highlight">50</i>&nbsp;    /**
<i class="no-highlight">51</i>&nbsp;     * &lt;code&gt;true&lt;/code&gt; iff this level is currently in progress, i.e. players
<i class="no-highlight">52</i>&nbsp;     * and NPCs can move.
<i class="no-highlight">53</i>&nbsp;     */
<i class="no-highlight">54</i>&nbsp;    private boolean inProgress;
<i class="no-highlight">55</i>&nbsp;
<i class="no-highlight">56</i>&nbsp;    /**
<i class="no-highlight">57</i>&nbsp;     * The squares from which players can start this game.
<i class="no-highlight">58</i>&nbsp;     */
<i class="no-highlight">59</i>&nbsp;    private final List&lt;Square&gt; startSquares;
<i class="no-highlight">60</i>&nbsp;
<i class="no-highlight">61</i>&nbsp;    /**
<i class="no-highlight">62</i>&nbsp;     * The start current selected starting square.
<i class="no-highlight">63</i>&nbsp;     */
<i class="no-highlight">64</i>&nbsp;    private int startSquareIndex;
<i class="no-highlight">65</i>&nbsp;
<i class="no-highlight">66</i>&nbsp;    /**
<i class="no-highlight">67</i>&nbsp;     * The players on this level.
<i class="no-highlight">68</i>&nbsp;     */
<i class="no-highlight">69</i>&nbsp;    private final List&lt;Player&gt; players;
<i class="no-highlight">70</i>&nbsp;
<i class="no-highlight">71</i>&nbsp;    /**
<i class="no-highlight">72</i>&nbsp;     * The table of possible collisions between units.
<i class="no-highlight">73</i>&nbsp;     */
<i class="no-highlight">74</i>&nbsp;    private final CollisionMap collisions;
<i class="no-highlight">75</i>&nbsp;
<i class="no-highlight">76</i>&nbsp;    /**
<i class="no-highlight">77</i>&nbsp;     * The objects observing this level.
<i class="no-highlight">78</i>&nbsp;     */
<i class="no-highlight">79</i>&nbsp;    private final Set&lt;LevelObserver&gt; observers;
<i class="no-highlight">80</i>&nbsp;
<i class="no-highlight">81</i>&nbsp;    /**
<i class="no-highlight">82</i>&nbsp;     * Creates a new level for the board.
<i class="no-highlight">83</i>&nbsp;     *
<i class="no-highlight">84</i>&nbsp;     * @param board
<i class="no-highlight">85</i>&nbsp;     *            The board for the level.
<i class="no-highlight">86</i>&nbsp;     * @param ghosts
<i class="no-highlight">87</i>&nbsp;     *            The ghosts on the board.
<i class="no-highlight">88</i>&nbsp;     * @param startPositions
<i class="no-highlight">89</i>&nbsp;     *            The squares on which players start on this board.
<i class="no-highlight">90</i>&nbsp;     * @param collisionMap
<i class="no-highlight">91</i>&nbsp;     *            The collection of collisions that should be handled.
<i class="no-highlight">92</i>&nbsp;     */
<i class="no-highlight">93</i>&nbsp;    public Level(Board board, List&lt;Ghost&gt; ghosts, List&lt;Square&gt; startPositions,
<b class="nc"><i class="no-highlight">94</i>&nbsp;                 CollisionMap collisionMap) {</b>
<b class="nc"><i class="no-highlight">95</i>&nbsp;        assert board != null;</b>
<b class="nc"><i class="no-highlight">96</i>&nbsp;        assert ghosts != null;</b>
<b class="nc"><i class="no-highlight">97</i>&nbsp;        assert startPositions != null;</b>
<i class="no-highlight">98</i>&nbsp;
<b class="nc"><i class="no-highlight">99</i>&nbsp;        this.board = board;</b>
<b class="nc"><i class="no-highlight">100</i>&nbsp;        this.inProgress = false;</b>
<b class="nc"><i class="no-highlight">101</i>&nbsp;        this.npcs = new HashMap&lt;&gt;();</b>
<b class="nc"><i class="no-highlight">102</i>&nbsp;        for (Ghost ghost : ghosts) {</b>
<b class="nc"><i class="no-highlight">103</i>&nbsp;            npcs.put(ghost, null);</b>
<b class="nc"><i class="no-highlight">104</i>&nbsp;        }</b>
<b class="nc"><i class="no-highlight">105</i>&nbsp;        this.startSquares = startPositions;</b>
<b class="nc"><i class="no-highlight">106</i>&nbsp;        this.startSquareIndex = 0;</b>
<b class="nc"><i class="no-highlight">107</i>&nbsp;        this.players = new ArrayList&lt;&gt;();</b>
<b class="nc"><i class="no-highlight">108</i>&nbsp;        this.collisions = collisionMap;</b>
<b class="nc"><i class="no-highlight">109</i>&nbsp;        this.observers = new HashSet&lt;&gt;();</b>
<i class="no-highlight">110</i>&nbsp;    }
<i class="no-highlight">111</i>&nbsp;
<i class="no-highlight">112</i>&nbsp;    /**
<i class="no-highlight">113</i>&nbsp;     * Adds an observer that will be notified when the level is won or lost.
<i class="no-highlight">114</i>&nbsp;     *
<i class="no-highlight">115</i>&nbsp;     * @param observer
<i class="no-highlight">116</i>&nbsp;     *            The observer that will be notified.
<i class="no-highlight">117</i>&nbsp;     */
<i class="no-highlight">118</i>&nbsp;    public void addObserver(LevelObserver observer) {
<b class="nc"><i class="no-highlight">119</i>&nbsp;        observers.add(observer);</b>
<i class="no-highlight">120</i>&nbsp;    }
<i class="no-highlight">121</i>&nbsp;
<i class="no-highlight">122</i>&nbsp;    /**
<i class="no-highlight">123</i>&nbsp;     * Removes an observer if it was listed.
<i class="no-highlight">124</i>&nbsp;     *
<i class="no-highlight">125</i>&nbsp;     * @param observer
<i class="no-highlight">126</i>&nbsp;     *            The observer to be removed.
<i class="no-highlight">127</i>&nbsp;     */
<i class="no-highlight">128</i>&nbsp;    public void removeObserver(LevelObserver observer) {
<b class="nc"><i class="no-highlight">129</i>&nbsp;        observers.remove(observer);</b>
<i class="no-highlight">130</i>&nbsp;    }
<i class="no-highlight">131</i>&nbsp;
<i class="no-highlight">132</i>&nbsp;    /**
<i class="no-highlight">133</i>&nbsp;     * Registers a player on this level, assigning him to a starting position. A
<i class="no-highlight">134</i>&nbsp;     * player can only be registered once, registering a player again will have
<i class="no-highlight">135</i>&nbsp;     * no effect.
<i class="no-highlight">136</i>&nbsp;     *
<i class="no-highlight">137</i>&nbsp;     * @param player
<i class="no-highlight">138</i>&nbsp;     *            The player to register.
<i class="no-highlight">139</i>&nbsp;     */
<i class="no-highlight">140</i>&nbsp;    public void registerPlayer(Player player) {
<b class="nc"><i class="no-highlight">141</i>&nbsp;        assert player != null;</b>
<b class="nc"><i class="no-highlight">142</i>&nbsp;        assert !startSquares.isEmpty();</b>
<i class="no-highlight">143</i>&nbsp;
<b class="nc"><i class="no-highlight">144</i>&nbsp;        if (players.contains(player)) {</b>
<i class="no-highlight">145</i>&nbsp;            return;
<i class="no-highlight">146</i>&nbsp;        }
<b class="nc"><i class="no-highlight">147</i>&nbsp;        players.add(player);</b>
<b class="nc"><i class="no-highlight">148</i>&nbsp;        Square square = startSquares.get(startSquareIndex);</b>
<b class="nc"><i class="no-highlight">149</i>&nbsp;        player.occupy(square);</b>
<b class="nc"><i class="no-highlight">150</i>&nbsp;        startSquareIndex++;</b>
<b class="nc"><i class="no-highlight">151</i>&nbsp;        startSquareIndex %= startSquares.size();</b>
<i class="no-highlight">152</i>&nbsp;    }
<i class="no-highlight">153</i>&nbsp;
<i class="no-highlight">154</i>&nbsp;    /**
<i class="no-highlight">155</i>&nbsp;     * Returns the board of this level.
<i class="no-highlight">156</i>&nbsp;     *
<i class="no-highlight">157</i>&nbsp;     * @return The board of this level.
<i class="no-highlight">158</i>&nbsp;     */
<i class="no-highlight">159</i>&nbsp;    public Board getBoard() {
<b class="nc"><i class="no-highlight">160</i>&nbsp;        return board;</b>
<i class="no-highlight">161</i>&nbsp;    }
<i class="no-highlight">162</i>&nbsp;
<i class="no-highlight">163</i>&nbsp;    /**
<i class="no-highlight">164</i>&nbsp;     * Moves the unit into the given direction if possible and handles all
<i class="no-highlight">165</i>&nbsp;     * collisions.
<i class="no-highlight">166</i>&nbsp;     *
<i class="no-highlight">167</i>&nbsp;     * @param unit
<i class="no-highlight">168</i>&nbsp;     *            The unit to move.
<i class="no-highlight">169</i>&nbsp;     * @param direction
<i class="no-highlight">170</i>&nbsp;     *            The direction to move the unit in.
<i class="no-highlight">171</i>&nbsp;     */
<i class="no-highlight">172</i>&nbsp;    public void move(Unit unit, Direction direction) {
<b class="nc"><i class="no-highlight">173</i>&nbsp;        assert unit != null;</b>
<b class="nc"><i class="no-highlight">174</i>&nbsp;        assert direction != null;</b>
<b class="nc"><i class="no-highlight">175</i>&nbsp;        assert unit.hasSquare();</b>
<i class="no-highlight">176</i>&nbsp;
<b class="nc"><i class="no-highlight">177</i>&nbsp;        if (!isInProgress()) {</b>
<i class="no-highlight">178</i>&nbsp;            return;
<i class="no-highlight">179</i>&nbsp;        }
<i class="no-highlight">180</i>&nbsp;
<b class="nc"><i class="no-highlight">181</i>&nbsp;        synchronized (moveLock) {</b>
<b class="nc"><i class="no-highlight">182</i>&nbsp;            unit.setDirection(direction);</b>
<b class="nc"><i class="no-highlight">183</i>&nbsp;            Square location = unit.getSquare();</b>
<b class="nc"><i class="no-highlight">184</i>&nbsp;            Square destination = location.getSquareAt(direction);</b>
<i class="no-highlight">185</i>&nbsp;
<b class="nc"><i class="no-highlight">186</i>&nbsp;            if (destination.isAccessibleTo(unit)) {</b>
<b class="nc"><i class="no-highlight">187</i>&nbsp;                List&lt;Unit&gt; occupants = destination.getOccupants();</b>
<b class="nc"><i class="no-highlight">188</i>&nbsp;                unit.occupy(destination);</b>
<b class="nc"><i class="no-highlight">189</i>&nbsp;                for (Unit occupant : occupants) {</b>
<b class="nc"><i class="no-highlight">190</i>&nbsp;                    collisions.collide(unit, occupant);</b>
<b class="nc"><i class="no-highlight">191</i>&nbsp;                }</b>
<i class="no-highlight">192</i>&nbsp;            }
<b class="nc"><i class="no-highlight">193</i>&nbsp;            updateObservers();</b>
<b class="nc"><i class="no-highlight">194</i>&nbsp;        }</b>
<i class="no-highlight">195</i>&nbsp;    }
<i class="no-highlight">196</i>&nbsp;
<i class="no-highlight">197</i>&nbsp;    /**
<i class="no-highlight">198</i>&nbsp;     * Starts or resumes this level, allowing movement and (re)starting the
<i class="no-highlight">199</i>&nbsp;     * NPCs.
<i class="no-highlight">200</i>&nbsp;     */
<i class="no-highlight">201</i>&nbsp;    public void start() {
<b class="nc"><i class="no-highlight">202</i>&nbsp;        synchronized (startStopLock) {</b>
<b class="nc"><i class="no-highlight">203</i>&nbsp;            if (isInProgress()) {</b>
<b class="nc"><i class="no-highlight">204</i>&nbsp;                return;</b>
<i class="no-highlight">205</i>&nbsp;            }
<b class="nc"><i class="no-highlight">206</i>&nbsp;            startNPCs();</b>
<b class="nc"><i class="no-highlight">207</i>&nbsp;            inProgress = true;</b>
<b class="nc"><i class="no-highlight">208</i>&nbsp;            updateObservers();</b>
<b class="nc"><i class="no-highlight">209</i>&nbsp;        }</b>
<i class="no-highlight">210</i>&nbsp;    }
<i class="no-highlight">211</i>&nbsp;
<i class="no-highlight">212</i>&nbsp;    /**
<i class="no-highlight">213</i>&nbsp;     * Stops or pauses this level, no longer allowing any movement on the board
<i class="no-highlight">214</i>&nbsp;     * and stopping all NPCs.
<i class="no-highlight">215</i>&nbsp;     */
<i class="no-highlight">216</i>&nbsp;    public void stop() {
<b class="nc"><i class="no-highlight">217</i>&nbsp;        synchronized (startStopLock) {</b>
<b class="nc"><i class="no-highlight">218</i>&nbsp;            if (!isInProgress()) {</b>
<b class="nc"><i class="no-highlight">219</i>&nbsp;                return;</b>
<i class="no-highlight">220</i>&nbsp;            }
<b class="nc"><i class="no-highlight">221</i>&nbsp;            stopNPCs();</b>
<b class="nc"><i class="no-highlight">222</i>&nbsp;            inProgress = false;</b>
<b class="nc"><i class="no-highlight">223</i>&nbsp;        }</b>
<i class="no-highlight">224</i>&nbsp;    }
<i class="no-highlight">225</i>&nbsp;
<i class="no-highlight">226</i>&nbsp;    /**
<i class="no-highlight">227</i>&nbsp;     * Starts all NPC movement scheduling.
<i class="no-highlight">228</i>&nbsp;     */
<i class="no-highlight">229</i>&nbsp;    private void startNPCs() {
<b class="nc"><i class="no-highlight">230</i>&nbsp;        for (final Ghost npc : npcs.keySet()) {</b>
<b class="nc"><i class="no-highlight">231</i>&nbsp;            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();</b>
<i class="no-highlight">232</i>&nbsp;
<b class="nc"><i class="no-highlight">233</i>&nbsp;            service.schedule(new NpcMoveTask(service, npc),</b>
<b class="nc"><i class="no-highlight">234</i>&nbsp;                npc.getInterval() / 2, TimeUnit.MILLISECONDS);</b>
<i class="no-highlight">235</i>&nbsp;
<b class="nc"><i class="no-highlight">236</i>&nbsp;            npcs.put(npc, service);</b>
<b class="nc"><i class="no-highlight">237</i>&nbsp;        }</b>
<i class="no-highlight">238</i>&nbsp;    }
<i class="no-highlight">239</i>&nbsp;
<i class="no-highlight">240</i>&nbsp;    /**
<i class="no-highlight">241</i>&nbsp;     * Stops all NPC movement scheduling and interrupts any movements being
<i class="no-highlight">242</i>&nbsp;     * executed.
<i class="no-highlight">243</i>&nbsp;     */
<i class="no-highlight">244</i>&nbsp;    private void stopNPCs() {
<b class="nc"><i class="no-highlight">245</i>&nbsp;        for (Entry&lt;Ghost, ScheduledExecutorService&gt; entry : npcs.entrySet()) {</b>
<b class="nc"><i class="no-highlight">246</i>&nbsp;            ScheduledExecutorService schedule = entry.getValue();</b>
<b class="nc"><i class="no-highlight">247</i>&nbsp;            assert schedule != null;</b>
<b class="nc"><i class="no-highlight">248</i>&nbsp;            schedule.shutdownNow();</b>
<b class="nc"><i class="no-highlight">249</i>&nbsp;        }</b>
<i class="no-highlight">250</i>&nbsp;    }
<i class="no-highlight">251</i>&nbsp;
<i class="no-highlight">252</i>&nbsp;    /**
<i class="no-highlight">253</i>&nbsp;     * Returns whether this level is in progress, i.e. whether moves can be made
<i class="no-highlight">254</i>&nbsp;     * on the board.
<i class="no-highlight">255</i>&nbsp;     *
<i class="no-highlight">256</i>&nbsp;     * @return &lt;code&gt;true&lt;/code&gt; iff this level is in progress.
<i class="no-highlight">257</i>&nbsp;     */
<i class="no-highlight">258</i>&nbsp;    public boolean isInProgress() {
<b class="nc"><i class="no-highlight">259</i>&nbsp;        return inProgress;</b>
<i class="no-highlight">260</i>&nbsp;    }
<i class="no-highlight">261</i>&nbsp;
<i class="no-highlight">262</i>&nbsp;    /**
<i class="no-highlight">263</i>&nbsp;     * Updates the observers about the state of this level.
<i class="no-highlight">264</i>&nbsp;     */
<i class="no-highlight">265</i>&nbsp;    private void updateObservers() {
<b class="nc"><i class="no-highlight">266</i>&nbsp;        if (!isAnyPlayerAlive()) {</b>
<b class="nc"><i class="no-highlight">267</i>&nbsp;            for (LevelObserver observer : observers) {</b>
<b class="nc"><i class="no-highlight">268</i>&nbsp;                observer.levelLost();</b>
<b class="nc"><i class="no-highlight">269</i>&nbsp;            }</b>
<i class="no-highlight">270</i>&nbsp;        }
<b class="nc"><i class="no-highlight">271</i>&nbsp;        if (remainingPellets() == 0) {</b>
<b class="nc"><i class="no-highlight">272</i>&nbsp;            for (LevelObserver observer : observers) {</b>
<b class="nc"><i class="no-highlight">273</i>&nbsp;                observer.levelWon();</b>
<b class="nc"><i class="no-highlight">274</i>&nbsp;            }</b>
<i class="no-highlight">275</i>&nbsp;        }
<i class="no-highlight">276</i>&nbsp;    }
<i class="no-highlight">277</i>&nbsp;
<i class="no-highlight">278</i>&nbsp;    /**
<i class="no-highlight">279</i>&nbsp;     * Returns &lt;code&gt;true&lt;/code&gt; iff at least one of the players in this level
<i class="no-highlight">280</i>&nbsp;     * is alive.
<i class="no-highlight">281</i>&nbsp;     *
<i class="no-highlight">282</i>&nbsp;     * @return &lt;code&gt;true&lt;/code&gt; if at least one of the registered players is
<i class="no-highlight">283</i>&nbsp;     *         alive.
<i class="no-highlight">284</i>&nbsp;     */
<i class="no-highlight">285</i>&nbsp;    public boolean isAnyPlayerAlive() {
<b class="nc"><i class="no-highlight">286</i>&nbsp;        for (Player player : players) {</b>
<b class="nc"><i class="no-highlight">287</i>&nbsp;            if (player.isAlive()) {</b>
<b class="nc"><i class="no-highlight">288</i>&nbsp;                return true;</b>
<i class="no-highlight">289</i>&nbsp;            }
<b class="nc"><i class="no-highlight">290</i>&nbsp;        }</b>
<b class="nc"><i class="no-highlight">291</i>&nbsp;        return false;</b>
<i class="no-highlight">292</i>&nbsp;    }
<i class="no-highlight">293</i>&nbsp;
<i class="no-highlight">294</i>&nbsp;    /**
<i class="no-highlight">295</i>&nbsp;     * Counts the pellets remaining on the board.
<i class="no-highlight">296</i>&nbsp;     *
<i class="no-highlight">297</i>&nbsp;     * @return The amount of pellets remaining on the board.
<i class="no-highlight">298</i>&nbsp;     */
<i class="no-highlight">299</i>&nbsp;    public int remainingPellets() {
<b class="nc"><i class="no-highlight">300</i>&nbsp;        Board board = getBoard();</b>
<b class="nc"><i class="no-highlight">301</i>&nbsp;        int pellets = 0;</b>
<b class="nc"><i class="no-highlight">302</i>&nbsp;        for (int x = 0; x &lt; board.getWidth(); x++) {</b>
<b class="nc"><i class="no-highlight">303</i>&nbsp;            for (int y = 0; y &lt; board.getHeight(); y++) {</b>
<b class="nc"><i class="no-highlight">304</i>&nbsp;                for (Unit unit : board.squareAt(x, y).getOccupants()) {</b>
<b class="nc"><i class="no-highlight">305</i>&nbsp;                    if (unit instanceof Pellet) {</b>
<b class="nc"><i class="no-highlight">306</i>&nbsp;                        pellets++;</b>
<i class="no-highlight">307</i>&nbsp;                    }
<b class="nc"><i class="no-highlight">308</i>&nbsp;                }</b>
<i class="no-highlight">309</i>&nbsp;            }
<i class="no-highlight">310</i>&nbsp;        }
<b class="nc"><i class="no-highlight">311</i>&nbsp;        assert pellets &gt;= 0;</b>
<b class="nc"><i class="no-highlight">312</i>&nbsp;        return pellets;</b>
<i class="no-highlight">313</i>&nbsp;    }
<i class="no-highlight">314</i>&nbsp;
<i class="no-highlight">315</i>&nbsp;    /**
<i class="no-highlight">316</i>&nbsp;     * A task that moves an NPC and reschedules itself after it finished.
<i class="no-highlight">317</i>&nbsp;     *
<i class="no-highlight">318</i>&nbsp;     * @author Jeroen Roosen
<i class="no-highlight">319</i>&nbsp;     */
<i class="no-highlight">320</i>&nbsp;    private final class NpcMoveTask implements Runnable {
<i class="no-highlight">321</i>&nbsp;
<i class="no-highlight">322</i>&nbsp;        /**
<i class="no-highlight">323</i>&nbsp;         * The service executing the task.
<i class="no-highlight">324</i>&nbsp;         */
<i class="no-highlight">325</i>&nbsp;        private final ScheduledExecutorService service;
<i class="no-highlight">326</i>&nbsp;
<i class="no-highlight">327</i>&nbsp;        /**
<i class="no-highlight">328</i>&nbsp;         * The NPC to move.
<i class="no-highlight">329</i>&nbsp;         */
<i class="no-highlight">330</i>&nbsp;        private final Ghost npc;
<i class="no-highlight">331</i>&nbsp;
<i class="no-highlight">332</i>&nbsp;        /**
<i class="no-highlight">333</i>&nbsp;         * Creates a new task.
<i class="no-highlight">334</i>&nbsp;         *
<i class="no-highlight">335</i>&nbsp;         * @param service
<i class="no-highlight">336</i>&nbsp;         *            The service that executes the task.
<i class="no-highlight">337</i>&nbsp;         * @param npc
<i class="no-highlight">338</i>&nbsp;         *            The NPC to move.
<i class="no-highlight">339</i>&nbsp;         */
<b class="nc"><i class="no-highlight">340</i>&nbsp;        NpcMoveTask(ScheduledExecutorService service, Ghost npc) {</b>
<b class="nc"><i class="no-highlight">341</i>&nbsp;            this.service = service;</b>
<b class="nc"><i class="no-highlight">342</i>&nbsp;            this.npc = npc;</b>
<i class="no-highlight">343</i>&nbsp;        }
<i class="no-highlight">344</i>&nbsp;
<i class="no-highlight">345</i>&nbsp;        @Override
<i class="no-highlight">346</i>&nbsp;        public void run() {
<b class="nc"><i class="no-highlight">347</i>&nbsp;            Direction nextMove = npc.nextMove();</b>
<b class="nc"><i class="no-highlight">348</i>&nbsp;            if (nextMove != null) {</b>
<b class="nc"><i class="no-highlight">349</i>&nbsp;                move(npc, nextMove);</b>
<i class="no-highlight">350</i>&nbsp;            }
<b class="nc"><i class="no-highlight">351</i>&nbsp;            long interval = npc.getInterval();</b>
<b class="nc"><i class="no-highlight">352</i>&nbsp;            service.schedule(this, interval, TimeUnit.MILLISECONDS);</b>
<i class="no-highlight">353</i>&nbsp;        }
<i class="no-highlight">354</i>&nbsp;    }
<i class="no-highlight">355</i>&nbsp;
<i class="no-highlight">356</i>&nbsp;    /**
<i class="no-highlight">357</i>&nbsp;     * An observer that will be notified when the level is won or lost.
<i class="no-highlight">358</i>&nbsp;     *
<i class="no-highlight">359</i>&nbsp;     * @author Jeroen Roosen
<i class="no-highlight">360</i>&nbsp;     */
<i class="no-highlight">361</i>&nbsp;    public interface LevelObserver {
<i class="no-highlight">362</i>&nbsp;
<i class="no-highlight">363</i>&nbsp;        /**
<i class="no-highlight">364</i>&nbsp;         * The level has been won. Typically the level should be stopped when
<i class="no-highlight">365</i>&nbsp;         * this event is received.
<i class="no-highlight">366</i>&nbsp;         */
<i class="no-highlight">367</i>&nbsp;        void levelWon();
<i class="no-highlight">368</i>&nbsp;
<i class="no-highlight">369</i>&nbsp;        /**
<i class="no-highlight">370</i>&nbsp;         * The level has been lost. Typically the level should be stopped when
<i class="no-highlight">371</i>&nbsp;         * this event is received.
<i class="no-highlight">372</i>&nbsp;         */
<i class="no-highlight">373</i>&nbsp;        void levelLost();
<i class="no-highlight">374</i>&nbsp;    }
<i class="no-highlight">375</i>&nbsp;}
</div>
</pre>
</div>

<script type="text/javascript">
(function() {
    var msie = false, msie9 = false;
    /*@cc_on
      msie = true;
      @if (@_jscript_version >= 9)
        msie9 = true;
      @end
    @*/

    if (!msie || msie && msie9) {
        var codeBlock = document.getElementById('sourceCode');

        if (codeBlock) {
            hljs.highlightBlock(codeBlock);
        }
    }
})();
</script>

<div class="footer">
    
    <div style="float:right;">generated on 2022-05-16 18:35</div>
</div>
</body>
</html>
